package utils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class AlternateStateThreadPoolExecutor extends ThreadPoolExecutor {
	
	
	public enum STATE {FAST, SLOW, STEPBYSTEP, PAUSE};
	
	private static STATE currentState=STATE.PAUSE;
	
	private ReentrantLock pauseLock = new ReentrantLock();
	private Condition unpaused = pauseLock.newCondition();
	
	public static AlternateStateThreadPoolExecutor processExe;
	
	public AlternateStateThreadPoolExecutor() {
		super(30, Integer.MAX_VALUE, 100, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<Runnable>(999));
		AlternateStateThreadPoolExecutor.processExe=this;
	}

	public static STATE getState(){
		return currentState;
	}
	
	protected void beforeExecute(Thread t, Runnable r) {
		super.beforeExecute(t, r);
		
		pauseLock.lock();
		try {
			switch(currentState){
				case PAUSE :
					unpaused.await();
					break;
				case STEPBYSTEP :
					unpaused.await();
					break;
				case SLOW :
					unpaused.await(2, TimeUnit.SECONDS);
					break;
				case FAST :
					break;
			}
		}
		 catch (InterruptedException ie) {
	      t.interrupt();
	    } finally {
	      pauseLock.unlock();
	    }
	}

	public void pause() {
	    pauseLock.lock();
	    try {
	      currentState=STATE.PAUSE;
	    } finally {
	      pauseLock.unlock();
	    }
	}
	
	public void nextStep(){
		pauseLock.lock();
	    try {
	      unpaused.signalAll();
	    } finally {
	      pauseLock.unlock();
	    }
	}
	
	public void goSlow() {
	    pauseLock.lock();
	    try {
	      currentState=STATE.SLOW;
	      unpaused.signalAll();
	    } finally {
	      pauseLock.unlock();
	    }
	  }
	
	public void goFast() {
	    pauseLock.lock();
	    try {
	      currentState=STATE.FAST;
	      unpaused.signalAll();
	    } finally {
	      pauseLock.unlock();
	    }
	  }

	}

